/*

   MCL STRING - A component library of the Sigh misc. C library.

   Copyright (c) 2011, Sulaiman A. Mustafa

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
   
   ________________________________________________________________________
   
   Note:
      The functions contained herein are documented mcl_str.h 
      
   */      
      //////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////////////
   /////// What you where doing :                                           /////vv
   ///////                                                                  ////////
   ///////         Changing nulls to seterr stuffs                          ///////////
   ///////                                                                  ////////
   /////// 
   /*
            TL;DR guide:
            1. MCL strings are dealt with in two distinced ways:
                     buffer biganing / string beganing
                     
            
   */
   ///////                                                                  ////////
   ////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////
   /////////////////////////////////////////////////////////////////////////////////
   /////////////////////////////////////////////////////////////////////////////////
   /////////////////////////////////////////////////////////////////////////////////




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mcl/str.h"


mcl_str_t*    mcl_str_cat_z(mcl_str_t *dest, mcl_str_t *src){
   int old, new;
   mcl_str__prepare(dest);
   mcl_str__prepare(src);

   old=*(mcl_str__lenaddr(dest));
   new=old+*(mcl_str__lenaddr(src));

   dest=mcl_str___stretch(dest, new);
   mcl_str__checkmemalloc(dest, "mcl_str_cat_z");
   
   strncpy(mcl_str__straddr(dest)+old, mcl_str__straddr(src), new-old);
   *(mcl_str__lenaddr(dest))=new;
   mcl_str__terminate(dest);

   return mcl_str__straddr(dest);
}

mcl_str_t*    mcl_str_sub_cz(mcl_str_t *src, int start, int length){
   mcl_str_t* buf=NULL;

   mcl_str__prepare(src);
   
   if (start<0) start=*mcl_str__lenaddr(src)+start;
   if (length==-1) length=*mcl_str__lenaddr(src)-start;
   
   if (start<0 || length<0 ||
       start>=*mcl_str__lenaddr(src)||
       length+start>*mcl_str__lenaddr(src) ){
      mcl_str__debug(fprintf(stderr, "mcl_str_sub_cz: EINDEX (start: %-3d; length: %-3d; string length: %-3d)\n", start, length,*mcl_str__lenaddr(src)));
      return mcl_str___seterr(NULL, MCL_STR_EINDEX);
   }
   
   buf=mcl_str___sct(buf, (mcl_str__straddr(src)+start), length);
   mcl_str__checkmemalloc(buf, "mcl_str_sub_cz");
   return mcl_str__straddr(buf);
}

mcl_str_t* mcl_str_insert_z(mcl_str_t* str, mcl_str_t* section, int start, int length){
   mcl_str_t* buf;
   int lbuf, lsec;
   
   
   mcl_str__prepare(section);
   mcl_str__prepare(str);
   lsec=*(mcl_str__lenaddr(section));
   
   if ((*(mcl_str__lenaddr(str))-start)<0) {
      mcl_str__debug(fprintf(stderr, "error: start point out of range!\nstring length: %d\nstart point: %d\n", *(mcl_str__lenaddr(str)), start));
      return mcl_str___seterr(str, MCL_STR_EINDEX);
   }
   
   if ((*(mcl_str__lenaddr(str))-start-length)<0) {
      mcl_str__debug(fprintf(stderr, "error: attempting to replace non-existant string!\nstring length: %d\nstart point: %d\n", *(mcl_str__lenaddr(str)), start));
      return mcl_str___seterr(str, MCL_STR_EINDEX);
   }

   /* cuts of the last part of the string*/
   buf=mcl_str_sub_c(str, start+length, -1);
   mcl_str__prepare(buf);
   lbuf=*(mcl_str__lenaddr(buf));
   
   str=mcl_str___stretch(str, start+lsec+lbuf);
   mcl_str__checkmemalloc(str, "mcl_str_insert_z"); 
   
   strncpy(mcl_str__straddr(str)+start, mcl_str__straddr(section), lsec);
   strncpy(mcl_str__straddr(str)+start+lsec, mcl_str__straddr(buf), lbuf);
   
   *(mcl_str__lenaddr(str))=start+lsec+lbuf;

	mcl_str__terminate((str));
	
	
   mcl_str_free(mcl_str__straddr(buf));
   return mcl_str__straddr(str);
}
